package com.dcsgo.v1ch03;

import java.util.Scanner;

/**
 * 
 * @ClassName: SwitchStatementAndSwitchExpression
 * @Description: switch语句与switch表达式 直通式与非直通式
 * @author DCSGO
 * @date 2023-10-31 09:21:59
 */
public class SwitchStatementAndSwitchExpression {
	public static void main(String[] args) {
		/*
		 * case标签可以是: 类型为char byte short 或 int 的常量表达式 枚举常量 字符串字面量 多个字符串，用逗号分隔
		 */
		Scanner scan = new Scanner(System.in);
		System.out.println("请输入你的选择: ");
		String input = scan.next();
		switch (input) {
		case "YES", "Y", "y", "yes" -> System.out.println("你选择了是");
		case "NO", "N", "no", "n" -> System.out.println("你选择了否");
		}
		scan.close();
		System.out.println("程序结束...");
		/**
		 * 请输入你的选择: YES 你选择了是 程序结束...
		 */

		/**
		 * 为了对称，Java14引入了一个有直通行为的switch表达式，所以总共有4种不同形式的switch。
		 * 在有直通行为的形式中，每个case以一个冒号结束。如果case以箭头->结束，则没有 直通行为。不能在一个switch语句中混合使用冒号和箭头。
		 * 注意switch表达式中的yield关键字。与break类似，yield会终止执行。但与break 不同的是，yield还会生成一个值，这就是表达式的值。
		 * 要在switch表达式的一个分支中使用语句而不想有直通行为，就必须使用大括号和yield
		 */

		//下面这个例子中演示了为每个分支增加日志语句
		String seasonName = "Summer";
		int seasonCode = switch (seasonName) {
		case "Spring" -> {
			System.out.println("spring time!");
			yield 0;
		}
		case "Summer" -> {
			System.out.println("Summer time!");
			yield 1;
		}
		case "Fall" -> {
			System.out.println("Fall time!");
			yield 2;
		}
		case "Winter" -> {
			System.out.println("Winter time!");
			yield 3;
		}
		default -> {
			System.out.println(seasonName + " is not a season name!");
			yield -1;
		}
		};
		System.out.println(seasonName + " code is " +seasonCode);
		/**
		 * Summer time!
		 * Summer code is 1
		 */
		
		/*
		 * switch表达式的每个分支必须生成一个值。最常见的做法是，各个值跟在一个箭头->后面:
		 * case "Summer","Winter" -> 6;
		 * 如果无法做到，则使用yield语句。
		 */
		
		//switch的4种形式
		//无直通行为
		//表达式
		seasonName = "Spring";
		int numLetters = switch(seasonName)
			{
				case "Spring" ->
				{
					System.out.println("spring time!");
					yield 6;
				}
				case "Summer","Winter" -> 6;
				case "Fall" -> 4;
				default -> -1;
			};
		System.out.println("numLetters = " + numLetters);
		
		//语句
		seasonName = "Summer";
		switch(seasonName) {
		case "Spring" -> {
			System.out.println("spring time!");
			numLetters = 6;
		}
		case "Summer","Winter" -> numLetters = 6;
		case "Fall" -> numLetters = 4;
		default -> numLetters = -1;
		}
		System.out.println("numLetters = " + numLetters);
		
		//有直通行为
		//表达式
		seasonName = "Fall";
		numLetters = switch(seasonName) {
		case "Spring": 
			System.out.println("spring time!");
		case "Summer","Winter":
			yield 6;
		case "Fall":
			yield 4;
		default:
			yield -1;
		};
		System.out.println("numLetters = " + numLetters);
		
		//语句
		seasonName = "Autumn";
		switch(seasonName) {
		case "Spring":
			System.out.println("spring time!");
		case "Summer","Winter":
			numLetters = 6;
			break;
		case "Fall":
			numLetters = 4;
			break;
		default:
			numLetters = -1;
			break;
		}
		System.out.println("numLetters = " + numLetters);
		/**
		 * spring time!
		 * numLetters = 6
		 * numLetters = 6
		 * numLetters = 4
		 * numLetters = -1
		 */
		
		//完全可以在switch表达式的一个分支中抛出异常。
		//例如:
		//default -> throw new IllegalArgumentException("Not a season");
		
		/**
		 * switch表达式的关键是生成一个值(或者产生一个异常而失败)。不允许“跳出”switch
		 * 表达式:
		 * default -> {return -1};//ERROR
		 * 具体来讲，不能在switch表达式中使用return break continue 语句。
		 * switch有这么多种形式，要如何选择呢？
		 * 如果每个分支会为一个变量赋值或方法调用计算值，则用一个表达式生成值，然后使用这个值。
		 */
		 
	}
}
